package org.batatasframework.support.definition;

import org.batatasframework.support.database.TableInfo;
import org.batatasframework.support.definition.impl.TableDefinitionImpl.ConcatFieldDefintion;
import org.batatasframework.support.definition.impl.TableDefinitionImpl.DefaultFieldDefinition;
import org.batatasframework.support.definition.impl.TableDefinitionImpl.FormatFieldDefinition;

/**
 * <pre>
 * 负责生成和初始化{@link TableDefinition}对象的
 * 
 * 排序的问题未解决
 * 
 * 这个方法被调用的时候，需要进行安全关闭
 * </pre>
 * @author jackson
 *
 */
public interface TableDefinitionBuilder extends AutoCloseable{
	
	/** 
	 * <pre>创建一个join关联表 ；
	 * <font color="red">注意：创建关联表时一定要使用 {@link JoinDefinition#on(String)}或{@link JoinDefinition#on(org.batatasframework.support.database.sql.JoinType, String, String)}
	 * 来指定使用哪些字段进行关联。</font></pre>
	 */
	JoinDefinition join(String tableName, boolean mustJoin) throws Exception;

	JoinDefinition join(TableDefinitionResource tableDefinition, String tableName, boolean mustJoin) throws Exception;
	/** 参考：{@link #join(String)} */
	JoinDefinition join(TableInfo tableInfo, boolean mustJoin) throws Exception;
	/** 参考：{@link #join(String)} */
	JoinDefinition join(String schemaName, String catalogName, String tableName, boolean mustJoin) throws Exception;
	
	/** 添加一个可查询和可显示的字段，具体需要自己定义 */
	DefaultFieldDefinition field(String fieldName)throws Exception;
	/** 参考：{@link #field(String)} */
	DefaultFieldDefinition field(String title, String fieldName)throws Exception;
	/** 参考：{@link #field(String)} */
	DefaultFieldDefinition field(JoinDefinition joinTable, String fieldName)throws Exception;
	/** 参考：{@link #field(String)} */
	DefaultFieldDefinition field(JoinDefinition joinTable, String title, String fieldName)throws Exception;
	
	/** 几个字段组合成一个字段返回 */
	ConcatFieldDefintion concat(String title)throws Exception;
	/** 参考：{@link #concat(String)} */
	ConcatFieldDefintion concat(String title, FieldDefinitionSourcable...fieldSources)throws Exception;
	/** 参考：{@link #concat(String)} */
	ConcatFieldDefintion concat(String title, String...fieldNames)throws Exception;
	/** 参考：{@link #concat(String)} */
	ConcatFieldDefintion concat(String title, JoinDefinition joinTable, String...fieldNames)throws Exception;
	
	ConcatFieldDefintion concat(String title, String fieldName,JoinDefinition joinTable, String...fieldNames)throws Exception;
	
	/** 格式化字符串，以指定的数据库表的字段返回的值 */
	FormatFieldDefinition format(String title, String format)throws Exception;
	/** 参考：{@link #format(String, String)} */
	FormatFieldDefinition format(String title, String format, FieldDefinitionSourcable...fieldSources)throws Exception;
	/** 参考：{@link #format(String, String)} */
	FormatFieldDefinition format(String title, String format, String...fieldNames)throws Exception;
	/** 参考：{@link #format(String, String)} */
	FormatFieldDefinition format(String title, String format, JoinDefinition joinTable, String...fieldNames)throws Exception;
	
	/** 添加主表的固定查询条件 */
	ConditionDefinition condition(String query);
	/**
	 * 添加一个固定的查询条件；主表或关联表。
	 * @param joinTable 关联表
	 * @param query 查询条件，如：C_DELETED=0等固定的值
	 * @param must true表示，如果使用join连接，并且查询的结果集里不包含该关联表，这时是否也需要添加这个关联查询的条件
	 * @return 查询条件
	 */
	ConditionDefinition condition(JoinDefinition joinTable, String query, boolean must);
	
	/** 添加自定义的查询条件的选择项 */
	void query(String key, QueryDefinition queryDefinition);
	
	void sort(String...fields);
	void sort(JoinDefinition joinTable, String...fields);
	
	TableDefinition sourceTableDefinition();
	
	/**
	 * <pre>
	 * 自动匹配，也就是说如果某个字段没有被定义，但在数据库里，该字段的备注字段有值；
	 * 则可以考虑把这个字段自动解析成显示或查询的字段。
	 * </pre>
	 */
	void autoMatch() throws Exception;
	
	/**
	 * 参考：{@link #autoMatch()}
	 * @param fieldExcludes 被排除的字段，这些字段将不会被自动生成
	 * @throws Exception
	 */
	void autoMatch(String...fieldExcludes) throws Exception;
	
	/** 调用这个方法才能生成表的定义对象，这个定义对象应该只生成一次，以后直接引用就可以。相同的定义不应该生成多次 */
	TableDefinition build() throws Exception;
}
